/**
 * Orcamento.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package negocio.notas;

import java.io.IOException;
import java.util.*;
import persistencia.notas.POrcamento;
import utils.*;

/**
 *
 * @author jmsandy
 */
public class Orcamento {

    // <editor-fold defaultstate="collapsed" desc="FIELDS">
    private String cod_objeto;
    private Integer numOrcamento;
    private Integer numOrcFornecedor;
    private Date dtValidade = null;
    private Date dtOrcamento = null;
    private double valor = 0;
    private Integer situacao;
    private String fornecedor;
    private Boolean update;
    private Boolean isNew = true;
    private String errorMessage = "";
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="ACESSORES">
    // Atributo cod_objeto
    public String getCod_objeto() {
        return cod_objeto; }
    public void setCod_objeto(String cod_objeto) {
        this.cod_objeto = cod_objeto; }
    // Atributo numOrcamento
    public Integer getNumOrcamento() {
        return numOrcamento; }
    public void setNumOrcamento(Integer numOrcamento) {
        this.numOrcamento = numOrcamento; }
    // Atributo numOrcFornecedor
    public Integer getNumOrcFornecedor() {
        return numOrcFornecedor; }
    public void setNumOrcFornecedor(Integer numOrcFornecedor) {
        this.numOrcFornecedor = numOrcFornecedor; }
    // Atributo dtValidade
    public Date getDtValidade() {
        return dtValidade; }
    public void setDtValidade(Date dtValidade) {
        this.dtValidade = dtValidade; }
    // Atributo dtOrcamento
    public Date getDtOrcamento() {
        return dtOrcamento; }
    public void setDtOrcamento(Date dtOrcamento) {
        this.dtOrcamento = dtOrcamento; }
    // Atributo valor
    public double getValor() {
        return valor; }
    public void setValor(double valor) {
        this.valor = valor; }
    // Atributo situacao
    public Integer getSituacao() {
        return situacao; }
    public void setSituacao(Integer situacao) {
        this.situacao = situacao; }
    // Atributo fornecedor
    public String getFornecedor() {
        return fornecedor; }
    public void setFornecedor(String fornecedor) {
        this.fornecedor = fornecedor; }
    // Atributo update
    public Boolean getWasUpdated() {
        return update; }
    public void setWasUpdated(Boolean update) {
        this.update = update; }
    // Atributo isNew
    public Boolean getIsNew() {
        return isNew; }
    public void setIsNew(Boolean isNew) {
        this.isNew = isNew; }
    // Atributo errorMessage
    public String getErrorMessage() {
        return errorMessage; }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    public Orcamento(){
        this.update  = false;
        this.isNew   = true;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="METHODS">
    /**
     * Verifica se um objeto e novo
     * @return retorna verdadeiro se o objeto for novo
     */
    public Boolean isNew(){
        return this.isNew;
    }

    /**
     * Realiza a insercao de um objeto na base de dados
     * @return TRUE se o objeto foi persistido e FALSE caso contrario
     */
    public Boolean insert() throws IOException{
        Boolean ret = true;
        this.errorMessage = "";

        // Verifica se um objeto pode ser inserido no banco de dados
        if(validateFields()){
            POrcamento pOrcamento = new POrcamento();

            // Verifica se o objeto foi inserido com sucesso
            if(!pOrcamento.insert(this)){
                ret = false;
                this.errorMessage = ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG;
            }
            else{
                this.update = true;
                this.isNew = false;
            }
        }
        else{
            ret = false;
            this.errorMessage = this.errorMessage.equals("") ?
                               ErrorMessage.MSG_GERAL_OBRIG : this.errorMessage;
        }
        return ret;
    }

    /**
     * Realiza a atualizacao de um objeto na base de dados
     * @return TRUE se o objeto foi persistido e FALSE caso contrario
     */
    public Boolean update() throws IOException{
        Boolean ret = true;
        this.errorMessage = "";

        // Verifica se um objeto pode ser inserido no banco de dados
        this.update = true;
        if(validateFields()){
            POrcamento pOrcamento = new POrcamento();

            // Verifica se o objeto foi inserido com sucesso
            if(!pOrcamento.update(this)){
                ret = false;
                this.errorMessage = ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG;
            }
            else{
                this.update = true;
                this.isNew = false;
            }
        }
        else{
            ret = false;
            this.errorMessage = this.errorMessage.equals("") ?
                               ErrorMessage.MSG_GERAL_OBRIG : this.errorMessage;
        }
//
        return ret;
    }

    /**
     * Realiza a delecao de um objeto na base de dados
     * @return TRUE se o objeto foi persistido e FALSE caso contrario
     */
    public Boolean delete() throws IOException{
        Boolean ret = true;
        errorMessage = "";

        // Verifica se um objeto e novo
        if(!this.isNew()){
            POrcamento pOrcamento = new POrcamento();

            if(!pOrcamento.existsNota(this.cod_objeto)){
                // Verifica se o objeto foi deletado com sucesso
                if(!pOrcamento.delete(this)){
                    ret = false;
                    this.errorMessage = ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                        ErrorMessage.MSG_GERAL_LOG;
                }
            }
            else{
                ret = false;
                errorMessage = ErrorMessage.MSG_ORCAMENTO_EXCLUSAO;
            }
        }
        else ret = false;

        return ret;
    }

    /**
     * Recupera um orcamento pelo seu numero
     * @param numOrc numero do orcamento a ser recuperado
     * @return o orcamento recuperado
     */
    public Orcamento refresh(Integer numOrc){
        Orcamento orcamento = null;
        errorMessage = "";

        try{

            // Verifica se foi informado algum codigo
            if(numOrc > 0){
                // Recupera o orcamento em questao
                POrcamento pOrcamento = new POrcamento();
                orcamento = new Orcamento();

                orcamento = pOrcamento.refresh(numOrc.toString(),
                                                      POrcamento.K_REC_COD_ORC);
                this.errorMessage = pOrcamento.isError() ?
                                        ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                        ErrorMessage.MSG_GERAL_LOG : "";
            }
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            orcamento = null;
        }
        return orcamento;
    }

    /**
     * Recupera um orcamento pelo codigo do objeto
     * @param idObjeto identificador do objeto
     * @return o orcamento recuperado
     */
    public Orcamento refresh(String idObjeto){
        Orcamento orcamento = null;
        errorMessage = "";

        try{
            // Recupera o orcamento em questao
            POrcamento pOrcamento = new POrcamento();
            orcamento = new Orcamento();

            orcamento = pOrcamento.refresh(idObjeto,POrcamento.K_REC_COD_OBJETO);
            this.errorMessage = pOrcamento.isError() ?
                                    ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG : "";
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            orcamento = null;
        }
        return orcamento;
    }
    /**
     * Recupera o ultimo codigo inserido
     */
    public Integer recUltCodigo(){
        Integer lastCod = 0;
        errorMessage = "";

        try{
            POrcamento pOrcamento = new POrcamento();
            lastCod = pOrcamento.recUltCodigo();
            this.errorMessage = pOrcamento.isError() ?
                                    ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG : "";
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            lastCod = 0;
        }
        return lastCod;
    }

    /**
     * Recupera uma lista de orcamentos que satisfaca aos filtros informados
     * @param orcamento caracteristicas do orcamento a ser buscado
     * @return lista de orcamentos
     */
    public ArrayList<Orcamento> recLstOrcamentos(Orcamento orcamento){
        // Lista de orcamentos de retorno
        ArrayList<Orcamento> lstOrcamentos = new ArrayList<Orcamento>();
        errorMessage = "";

        try{
            // Recupera a lista de orcamentos
            POrcamento pOrcamento = new POrcamento();

            lstOrcamentos = pOrcamento.recLstOrcamentos(orcamento);
            this.errorMessage = pOrcamento.isError() ?
                                    ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG : "";
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            lstOrcamentos = null;
        }

        return lstOrcamentos;
    }

    /**
     * Verifica a existencia de uma nota para um dado fornecedor
     * @return TRUE se o objeto foi encontrado e FALSE caso contrario
     */
    public Boolean existsForn(String idFornecedor) throws IOException{
        POrcamento pOrcamento = new POrcamento();
        return pOrcamento.existsForn(idFornecedor);
    }

    // Realiza a validacao dos campos para insercao
    private Boolean validateFields(){
        Boolean ret = true;

        // Verifica se o campo esta marcado como atualizado
        if(this.isNew()) this.cod_objeto = GenerateID.gerarID();


        // Verifica se foi informado um fornecedor
        ret = this.fornecedor.isEmpty() ? false : true;

        if(ret){
            // Verifica se o valor do orcamento e maior que zero
            ret = this.valor > 0 ? true : false;

            if(ret){
                // Verifica se foi informada uma data de orcamento
                ret = this.dtOrcamento != null ? true : false;


                // Caso tenha sido informada uma data de validade a mesma deve
                // ser superior a data do orcamento
                if(ret && this.dtValidade != null){
                    ret = this.dtValidade.getTime() >=
                                      this.dtOrcamento.getTime() ? true : false;
                    errorMessage = ret ?
                                       "" : ErrorMessage.MSG_ORCAMENTO_VALIDADE;
                }

                if(ret){
                    Date date = new Date();
                    ret = date.getTime() >= this.dtOrcamento.getTime() ?
                                                                   true : false;
                    if(!ret) this.errorMessage = ErrorMessage.MSG_GERAL_DATA;
                }
            }
        }
        return ret;
    }
    //</editor-fold>
}